home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / util / misc / StripHunks.lha / Source / StripHunks.c < prev   
Encoding:
C/C++ Source or Header  |  1999-10-09  |  15.9 KB  |  668 lines

  1. #define NAME     "StripHunks"
  2. #define REVISION "8"
  3.  
  4. /* Programmheader
  5.  
  6.         Name:           StripHunks
  7.         Author:         SDI
  8.         Distribution:   PD
  9.         Description:    removes debug, symbol and name hunks
  10.         Compileropts:   -
  11.         Linkeropts:     -gsi -l amiga
  12.  
  13.  1.0   08.02.98 : first version
  14.  1.1   12.02.98 : compiled with SAS
  15.  1.2   10.03.98 : fixed SAS local base system
  16.  1.3   03.06.98 : fixed Enforcer hit
  17.  1.4   18.08.98 : wrote own strip routines and removed xfd use
  18.  1.5   04.12.98 : added lots of new options
  19.  1.6   12.12.98 : added sorting for short relocs
  20.  1.7   08.02.99 : fixed NOSTRIP options
  21.  1.8   09.10.99 : added SORTBACKWARDS
  22. */
  23.  
  24. #include <proto/dos.h>
  25. #include <proto/exec.h>
  26. #include <exec/memory.h>
  27. #include <dos/doshunks.h>
  28. #include "SDI_defines.h"
  29.  
  30. #define PARAM           "FILES/M,ONLYSHOW/S,ALL/S,SORT=SORTRELOC/S,"    \
  31.             "NOSTRIP/S,NSE=NOSTRIPEMPTY/S,NSN=NOSTRIPNAME/S,"\
  32.             "NSD=NOSTRIPDEBUG/S,NSS=NOSTRIPSYMBOL/S,"    \
  33.             "NSR=NOSTRIPRELOC/S,SBW=SORTBACKWARDS/S"
  34. #define PATHSIZE        256
  35.  
  36. struct Args {
  37.   STRPTR *files;
  38.   ULONG   onlyshow;
  39.   ULONG   all;
  40.   ULONG   sortreloc;
  41.   ULONG   nostrip;
  42.   ULONG   nostripempty;
  43.   ULONG   nostripname;
  44.   ULONG   nostripdebug;
  45.   ULONG   nostripsymbol;
  46.   ULONG   nostripreloc;
  47.   ULONG      sortbackwards;
  48. };
  49.  
  50. struct ExecBase *SysBase  = 0;
  51.  
  52. #ifdef __SASC
  53.   #define DOSBase dosbase
  54.   #define ASSIGN_DOS
  55. #else
  56.   struct DosLibrary *    DOSBase = 0;
  57.   #define ASSIGN_DOS    DOSBase = dosbase;
  58. #endif
  59.  
  60. #define STRIPFLAG_SORTRELOC        (1<<0)
  61. #define STRIPFLAG_NOSTRIPEMPTY        (1<<1)
  62. #define STRIPFLAG_NOSTRIPNAME        (1<<2)
  63. #define STRIPFLAG_NOSTRIPDEBUG        (1<<3)
  64. #define STRIPFLAG_NOSTRIPSYMBOL        (1<<4)
  65. #define STRIPFLAG_NOSTRIPRELOC        (1<<5)
  66.  
  67. #define STRIPFLAG_SORTBACKWARDS        (1<<8)
  68.  
  69. #define STRIPFLAG_SORTFAILED        (1<<10)
  70. #define STRIPFLAG_EMPTY            (1<<11)
  71. #define STRIPFLAG_NAME            (1<<12)
  72. #define STRIPFLAG_DEBUG            (1<<13)
  73. #define STRIPFLAG_SYMBOL        (1<<14)
  74. #define STRIPFLAG_RELOC            (1<<15)
  75. #define STRIPFLAG_RELOCSORT        (1<<16)
  76.  
  77. #define STRIPFLAG_SORTED        (1<<20)
  78. #define STRIPFLAG_STRIPPEDDEBUG        (1<<21)
  79. #define STRIPFLAG_STRIPPEDEMPTY        (1<<22)
  80. #define STRIPFLAG_STRIPPEDNAME        (1<<23)
  81. #define STRIPFLAG_STRIPPEDSYMBOL    (1<<24)
  82. #define STRIPFLAG_STRIPPEDRELOC        (1<<25)
  83.  
  84. LONG StripHunks(ULONG *buf, ULONG *rl, ULONG l, ULONG *resflag, ULONG flags);
  85. ULONG DoSort(ULONG *buf, ULONG *resflags, ULONG flags);
  86. ULONG DoSortShort(UWORD *buf, ULONG *resflags, ULONG flags);
  87. LONG SortList(struct RelocData *rd, ULONG size, ULONG flags);
  88. void DoCopy(ULONG *buf, ULONG j, ULONG skip, ULONG size);
  89.  
  90. struct RelocData {
  91.   UWORD num;
  92.   UWORD hunk;
  93.   ULONG data;
  94. };
  95.  
  96. ULONG start(void)
  97. {
  98.   ULONG ret = RETURN_FAIL;
  99.   struct DosLibrary *dosbase;
  100.  
  101.   SysBase = (*((struct ExecBase **) 4));
  102.   { /* test for WB and reply startup-message */
  103.     struct Process *task;
  104.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  105.     {
  106.       WaitPort(&task->pr_MsgPort);
  107.       Forbid();
  108.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  109.       return RETURN_FAIL;
  110.     }
  111.   }
  112.  
  113.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  114.   {
  115.    STRPTR none = 0;
  116.    struct Args args;
  117.    struct RDArgs *rda;
  118.  
  119.    ASSIGN_DOS
  120.    args.files = 0;
  121.    args.onlyshow = args.all = args.sortreloc = args.nostripname =
  122.    args.nostripempty = args.nostripdebug = args.nostripsymbol =
  123.    args.nostrip = args.nostripreloc = args.sortbackwards = 0;
  124.  
  125.    if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  126.    {
  127.     struct AnchorPath *APath;
  128.     ULONG flags = 0;
  129.  
  130.     if(args.sortbackwards)    flags |= STRIPFLAG_SORTBACKWARDS;
  131.     if(args.sortreloc)        flags |= STRIPFLAG_SORTRELOC;
  132.     if(args.nostripname)    flags |= STRIPFLAG_NOSTRIPNAME;
  133.     if(args.nostripempty)    flags |= STRIPFLAG_NOSTRIPEMPTY;
  134.     if(args.nostripdebug)    flags |= STRIPFLAG_NOSTRIPDEBUG;
  135.     if(args.nostripsymbol)    flags |= STRIPFLAG_NOSTRIPSYMBOL;
  136.     if(args.nostripreloc)    flags |= STRIPFLAG_NOSTRIPRELOC;
  137.     if(args.nostrip)        flags |= STRIPFLAG_NOSTRIPEMPTY|
  138.         STRIPFLAG_NOSTRIPNAME|STRIPFLAG_NOSTRIPDEBUG|
  139.         STRIPFLAG_NOSTRIPSYMBOL|STRIPFLAG_NOSTRIPRELOC;
  140.  
  141.     /* args.files is cleared, when no arguments passed -- OS bug? */
  142.     if(!args.files)
  143.       args.files = &none;
  144.  
  145.     if((APath = (struct AnchorPath *) AllocMem(sizeof(struct AnchorPath)+
  146.     PATHSIZE, MEMF_PUBLIC|MEMF_CLEAR)))
  147.     {
  148.      ULONG retval = ERROR_NO_MORE_ENTRIES;
  149.  
  150.      APath->ap_BreakBits = SIGBREAKF_CTRL_C;
  151.      APath->ap_Strlen = PATHSIZE;
  152.  
  153.      while(*args.files && retval == ERROR_NO_MORE_ENTRIES)
  154.      {
  155.       for(retval = MatchFirst(*args.files, APath); !retval;
  156.       retval = MatchNext(APath))
  157.       {
  158.        if(APath->ap_Flags & APF_DIDDIR)
  159.         APath->ap_Flags &= ~APF_DIDDIR;
  160.        else if(APath->ap_Info.fib_DirEntryType > 0)
  161.        {
  162.         if(args.all)
  163.          APath->ap_Flags |= APF_DODIR;
  164.        }
  165.        else
  166.        {
  167.         BPTR fh;
  168.         LONG err = 0;
  169.                
  170.         if((fh = Open(APath->ap_Buf, MODE_OLDFILE)))
  171.         {
  172.          struct FileInfoBlock *fib;
  173.  
  174.          if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
  175.          {
  176.           if(ExamineFH(fh, fib))
  177.           {
  178.            ULONG length;
  179.  
  180.            if((length = fib->fib_Size) > 4)
  181.            {
  182.             ULONG reslength;
  183.  
  184.             if(Read(fh, &reslength, 4) == 4)
  185.             {
  186.              if(reslength == HUNK_HEADER)
  187.              {
  188.               ULONG *buf;
  189.  
  190.               if((buf = (ULONG *) AllocMem(length+3, MEMF_ANY|MEMF_CLEAR)))
  191.               {
  192.                if(Read(fh, buf+1, length-4) == length-4)
  193.                {
  194.                 ULONG resflags = 0;
  195.                 *buf = reslength; /* store HUNK ID */
  196.  
  197.                 if((err = StripHunks(buf, &reslength, length, &resflags, flags)) > 0)
  198.                 {
  199.                  if(reslength < length || (resflags & STRIPFLAG_SORTED))
  200.                  {
  201.                   Printf("File '%s': ", APath->ap_Buf);
  202.                   if(resflags & STRIPFLAG_STRIPPEDNAME)
  203.                     Printf("NAME, ");
  204.                   if(resflags & STRIPFLAG_STRIPPEDDEBUG)
  205.                     Printf("DEBUG, ");
  206.                   if(resflags & STRIPFLAG_STRIPPEDSYMBOL)
  207.                     Printf("SYMBOL, ");
  208.                   if(resflags & STRIPFLAG_STRIPPEDRELOC)
  209.                     Printf("RELOC, ");
  210.                   if(resflags & STRIPFLAG_STRIPPEDEMPTY)
  211.                     Printf("EMPTY ");
  212.                   if(length-reslength)
  213.                     Printf("total %ld bytes stripped", length-reslength);
  214.                   if(resflags & STRIPFLAG_SORTED)
  215.                     Printf("%sRELOC sorted", length-reslength ? ", " : "");
  216.           Printf("\n");
  217.                   if(!args.onlyshow)
  218.                   {
  219.                    if(ChangeMode(CHANGE_FH,fh,EXCLUSIVE_LOCK))
  220.                    {
  221.                     if(!SetFileSize(fh,0,OFFSET_BEGINNING))
  222.                     {
  223.                      if(Write(fh, buf, reslength) != reslength)
  224.                       Printf("Write error on file '%s'\n", APath->ap_Buf);
  225.                     }
  226.                     else
  227.                       err = 0;
  228.                    }
  229.                    else
  230.                     err = 0;
  231.                   }
  232.                  }
  233.                 }
  234.                 if(err < 0 || (resflags&(STRIPFLAG_EMPTY|STRIPFLAG_NAME|
  235.                 STRIPFLAG_DEBUG|STRIPFLAG_SYMBOL|STRIPFLAG_RELOC|
  236.                 STRIPFLAG_SORTFAILED|STRIPFLAG_RELOCSORT)))
  237.                 {
  238.                   Printf("File '%s': ", APath->ap_Buf);
  239.                   if(err == -2)
  240.                   {
  241.                     Printf("Unknown hunk type");
  242.                     err = 1;
  243.                   }
  244.                   else if(err == -1)
  245.                   {
  246.                     Printf("Strange hunk structure or overlay");
  247.                     err = 1;
  248.                   } /* else StripHunks */
  249.                   else
  250.                   {
  251.                     if(resflags & STRIPFLAG_EMPTY)
  252.                       Printf("EMPTY, ");
  253.                     if(resflags & STRIPFLAG_NAME)
  254.                       Printf("NAME, ");
  255.                     if(resflags & STRIPFLAG_DEBUG)
  256.                       Printf("DEBUG, ");
  257.                     if(resflags & STRIPFLAG_SYMBOL)
  258.                       Printf("SYMBOL, ");
  259.                     if(resflags & (STRIPFLAG_RELOC|STRIPFLAG_RELOCSORT))
  260.                       Printf("RELOC, ");
  261.                     if(resflags & STRIPFLAG_SORTFAILED)
  262.                       Printf("UNSORTED, ");
  263.                     Printf("still exists");
  264.                   }
  265.                   Printf("\n");
  266.                 }
  267.                } /* Read */
  268.                FreeMem(buf, length+3);
  269.               } /* AllocMem */
  270.              } /* HUNK_HEADER ? */
  271.              else
  272.               err = 1;
  273.             } /* Read 4 */
  274.            } /* size > 4 */
  275.            else
  276.             err = 1;
  277.           } /* Examine */
  278.           FreeDosObject(DOS_FIB,fib);
  279.          } /* AlloDosObject */
  280.          if(fh)
  281.           Close(fh);
  282.         }
  283.         if(err < 0)
  284.          Printf("Error on file '%s'\n", APath->ap_Buf);
  285.        }
  286.       }
  287.       MatchEnd(APath);
  288.       ++args.files;
  289.      }
  290.      if(retval == ERROR_NO_MORE_ENTRIES)
  291.       ret = 0;
  292.  
  293.      FreeMem(APath, sizeof(struct AnchorPath)+PATHSIZE);
  294.     }
  295.     FreeArgs(rda);
  296.    }
  297.    if(ret)
  298.     PrintFault(IoErr(), 0);
  299.  
  300.    CloseLibrary((struct Library *) dosbase);
  301.   }
  302.   return ret;
  303. }
  304.  
  305. LONG StripHunks(ULONG *buf, ULONG *rl, ULONG l, ULONG *resflags, ULONG flags)
  306. {
  307.   LONG i, j, empty = 0, skipend = 0, ret = 1;
  308.   /* skipend -- should last empty hunk be skipped */
  309.  
  310.   if(l & 3 || buf[1] || buf[2] != buf[4]+1 || buf[3])
  311.     return -1;
  312.  
  313.   l >>= 2;
  314.   i = buf[2];
  315.   
  316.   for(j = 0; j < i; ++j)    /* empty hunks */
  317.   {
  318.     if(!buf[5+j])
  319.       ++empty;
  320.   }
  321.  
  322.   if(empty)
  323.   {
  324.     if(buf[4+j] || empty > 1 || (flags & STRIPFLAG_NOSTRIPEMPTY))
  325.     {
  326.       *resflags |= STRIPFLAG_EMPTY; empty = 0;
  327.     }
  328.     else            /* skip empty hunks at file end */
  329.     {
  330.       *resflags |= STRIPFLAG_STRIPPEDEMPTY;
  331.       DoCopy(buf, 4+(i--), 1, l--);
  332.       --buf[2];
  333.       --buf[4];
  334.     }
  335.   }
  336.  
  337.   j = (5+i);
  338.   while(j < l)
  339.   {
  340.     if(buf[j] == HUNK_DEBUG)
  341.     {
  342.       i = 2+buf[j+1];
  343.       if(flags & STRIPFLAG_NOSTRIPDEBUG)
  344.       {
  345.         j += i; *resflags |= STRIPFLAG_DEBUG;
  346.       }
  347.       else
  348.       {
  349.     *resflags |= STRIPFLAG_STRIPPEDDEBUG;
  350.         DoCopy(buf, j, i, l);
  351.         l -= i;
  352.       }
  353.     }
  354.     else if(buf[j] == HUNK_NAME)
  355.     {
  356.       i = 2+buf[j+1];
  357.       if(flags & STRIPFLAG_NOSTRIPNAME)
  358.       {
  359.         j += i; *resflags |= STRIPFLAG_NAME;
  360.       }
  361.       else
  362.       {
  363.     *resflags |= STRIPFLAG_STRIPPEDNAME;
  364.         DoCopy(buf, j, i, l);
  365.         l -= i;
  366.       }
  367.     }
  368.     else if(buf[j] == HUNK_SYMBOL)
  369.     {
  370.       i = j+1;
  371.       while(buf[i])
  372.     i += buf[i]+2;
  373.       i = i-j+1;
  374.       if(flags & STRIPFLAG_NOSTRIPSYMBOL)
  375.       {
  376.         j += i; *resflags |= STRIPFLAG_SYMBOL;
  377.       }
  378.       else
  379.       {
  380.     *resflags |= STRIPFLAG_STRIPPEDSYMBOL;
  381.         DoCopy(buf, j, i, l);
  382.         l -= i;
  383.       }
  384.     }
  385.     else if((buf[j]&0xFFFFFF) == HUNK_CODE || (buf[j]&0xFFFFFF) == HUNK_DATA)
  386.     {
  387.       if(empty && !buf[j+1])
  388.       {
  389.     *resflags |= STRIPFLAG_STRIPPEDEMPTY;
  390.         DoCopy(buf, j, 2, l);
  391.         l -= 2;
  392.         skipend = 1;
  393.       }
  394.       else
  395.         j += 2+buf[j+1];
  396.     }
  397.     else if((buf[j]&0xFFFFFF) == HUNK_BSS)
  398.     {
  399.       if(empty && !buf[j+1])
  400.       {
  401.     *resflags |= STRIPFLAG_STRIPPEDEMPTY;
  402.         DoCopy(buf, j, 2, l);
  403.         l -= 2;
  404.         skipend = 1;
  405.       }
  406.       else
  407.         j += 2;
  408.     }
  409.     else if(buf[j] == HUNK_END)
  410.     {
  411.       if(skipend)
  412.       {
  413.         DoCopy(buf, j, 1, l--);
  414.         skipend = 0;
  415.       }
  416.       else
  417.         ++j;
  418.     }
  419.     else if(buf[j] == HUNK_RELOC32)
  420.     {
  421.       if(!buf[j+1])            /* empty reloc */
  422.       {
  423.         if(flags & STRIPFLAG_NOSTRIPRELOC)
  424.         {
  425.           j += 2; *resflags |= STRIPFLAG_RELOC;
  426.         }
  427.         else
  428.         {
  429.       *resflags |= STRIPFLAG_STRIPPEDRELOC;
  430.           DoCopy(buf, j, 2, l);
  431.           l -= 2;
  432.         }
  433.       }
  434.       else
  435.       {
  436.         ++j;
  437.         i = DoSort(buf + j, resflags, flags);
  438.         while(buf[j])
  439.         {
  440.       j += 2+buf[j];
  441.         }
  442.         ++j;
  443.         if(i)
  444.         {
  445.       *resflags |= STRIPFLAG_STRIPPEDRELOC;
  446.           DoCopy(buf, j, i, l);
  447.           l -= i;
  448.         }
  449.         if(skipend)
  450.           return -1;
  451.       }
  452.     }
  453.     else if(buf[j] == HUNK_DREL32 || buf[j] == HUNK_RELOC32SHORT)
  454.     {
  455.       UWORD *b;
  456.  
  457.       b = (UWORD *) (buf+j+1);
  458.  
  459.       if(*b == 0)            /* empty reloc */
  460.       {
  461.         if(flags & STRIPFLAG_NOSTRIPRELOC)
  462.         {
  463.           j += 2; *resflags |= STRIPFLAG_RELOC;
  464.         }
  465.         else
  466.         {
  467.       *resflags |= STRIPFLAG_STRIPPEDRELOC;
  468.           DoCopy(buf, j, 2, l);
  469.           l -= 2;
  470.         }
  471.       }
  472.       else
  473.       {
  474.         i = DoSortShort(b, resflags, flags);
  475.         while(*b)
  476.         {
  477.       b += 2+(*b);
  478.         }
  479.         j = (((STRPTR) (b+2)) - ((STRPTR) buf))>>2;
  480.         if(i)
  481.         {
  482.       *resflags |= STRIPFLAG_STRIPPEDRELOC;
  483.           DoCopy(buf, j, i>>1, l);
  484.           l -= i;
  485.         }
  486.         if(skipend)
  487.           return -1;
  488.       }
  489.     }
  490.     else
  491.       return -2;
  492.   }
  493.  
  494.   *rl = l<<2;
  495.   return ret;
  496. }
  497.  
  498. ULONG DoSort(ULONG *buf, ULONG *resflags, ULONG flags)
  499. {
  500.   ULONG num, size;
  501.   ULONG k, i, j, l;
  502.   struct RelocData *rd;
  503.  
  504.   if(!(flags & STRIPFLAG_SORTRELOC))
  505.     return 0;
  506.  
  507.   k = num = 0;
  508.   while(buf[k])
  509.   {
  510.     num += buf[k];
  511.     k += 2+buf[k];
  512.   }
  513.  
  514.   if(!(rd = (struct RelocData *) AllocMem(sizeof(struct RelocData)*num,MEMF_ANY)))
  515.   {
  516.     *resflags |= STRIPFLAG_SORTFAILED; return 0;
  517.   }
  518.  
  519.   k = j = l = 0;
  520.   while(buf[k])
  521.   {
  522.     for(i = 0; i < buf[k]; ++i)
  523.     {
  524.       rd[j].hunk = buf[k+1];
  525.       rd[j].num = (flags & STRIPFLAG_NOSTRIPRELOC) ? buf[k+1]*256+l : buf[k+1];
  526.       rd[j++].data = buf[k+2+i];
  527.     }
  528.     k += 2+buf[k];
  529.     ++l;
  530.   }
  531.  
  532.   size = ++k;
  533.   if(SortList(rd, num, flags))
  534.     *resflags |= STRIPFLAG_SORTED;
  535.   for(l = k = 0; l < num;)
  536.   {
  537.     for(j = 0; rd[l+j].num == rd[l].num && l+j<num; ++j)
  538.       ;
  539.     if(rd[l].hunk == rd[l+j].hunk)
  540.       *resflags |= STRIPFLAG_RELOCSORT;
  541.     buf[k++] = j;
  542.     buf[k++] = rd[l].hunk;
  543.     while(j--)
  544.       buf[k++] = rd[l++].data;
  545.   }
  546.   buf[k++] = 0;
  547.  
  548.   FreeMem(rd, sizeof(struct RelocData)*num);
  549.  
  550.   return size-k;
  551. }
  552.  
  553. ULONG DoSortShort(UWORD *buf, ULONG *resflags, ULONG flags)
  554. {
  555.   ULONG num, size;
  556.   ULONG k, i, j, l;
  557.   struct RelocData *rd;
  558.  
  559.   if(!(flags & STRIPFLAG_SORTRELOC))
  560.     return 0;
  561.  
  562.   k = num = 0;
  563.   while(buf[k])
  564.   {
  565.     num += buf[k];
  566.     k += 2+buf[k];
  567.   }
  568.  
  569.   if(!(rd = (struct RelocData *) AllocMem(sizeof(struct RelocData)*num,MEMF_ANY)))
  570.   {
  571.     *resflags |= STRIPFLAG_SORTFAILED; return 0;
  572.   }
  573.  
  574.   k = j = l = 0;
  575.   while(buf[k])
  576.   {
  577.     for(i = 0; i < buf[k]; ++i)
  578.     {
  579.       rd[j].hunk = buf[k+1];
  580.       rd[j].num = (flags & STRIPFLAG_NOSTRIPRELOC) ? buf[k+1]*256+l : buf[k+1];
  581.       rd[j++].data = buf[k+2+i];
  582.     }
  583.     k += 2+buf[k];
  584.     ++l;
  585.   }
  586.  
  587.   if((size = ++k) & 1)
  588.     ++size;
  589.   if(SortList(rd, num, flags))
  590.     *resflags |= STRIPFLAG_SORTED;
  591.   for(l = k = 0; l < num;)
  592.   {
  593.     for(j = 0; rd[l+j].num == rd[l].num && l+j<num; ++j)
  594.       ;
  595.     if(rd[l].hunk == rd[l+j].hunk)
  596.       *resflags |= STRIPFLAG_RELOCSORT;
  597.     buf[k++] = j;
  598.     buf[k++] = rd[l].hunk;
  599.     while(j--)
  600.       buf[k++] = rd[l++].data;
  601.   }
  602.   buf[k++] = 0;
  603.   if(k & 1)
  604.     buf[k++] = 0;
  605.  
  606.   FreeMem(rd, sizeof(struct RelocData)*num);
  607.  
  608.   return size-k;
  609. }
  610.  
  611. LONG SortList(struct RelocData *rd, ULONG size, ULONG flags)
  612. {
  613.   ULONG i, j, k;
  614.   LONG res = 0;
  615.   struct RelocData s;
  616.  
  617.   if(flags & STRIPFLAG_SORTBACKWARDS)
  618.   {
  619.     for(i = 0; i < size; ++i)
  620.     {
  621.       for(j = k = i; j < size; ++j)
  622.       {
  623.         if(rd[j].num < rd[k].num || (rd[j].num == rd[k].num && rd[j].data > rd[k].data))
  624.           k = j;
  625.       }
  626.       if(k != i)
  627.       {
  628.         s = rd[i];
  629.         rd[i] = rd[k];
  630.         rd[k] = s;
  631.         res = 1;
  632.       }
  633.     }
  634.   }
  635.   else
  636.   {
  637.     for(i = 0; i < size; ++i)
  638.     {
  639.       for(j = k = i; j < size; ++j)
  640.       {
  641.         if(rd[j].num < rd[k].num || (rd[j].num == rd[k].num && rd[j].data < rd[k].data))
  642.           k = j;
  643.       }
  644.       if(k != i)
  645.       {
  646.         s = rd[i];
  647.         rd[i] = rd[k];
  648.         rd[k] = s;
  649.         res = 1;
  650.       }
  651.     }
  652.   }
  653.   return res;
  654. }
  655.  
  656. void DoCopy(ULONG *buf, ULONG j, ULONG skip, ULONG size)
  657. {
  658.   ULONG i;
  659.  
  660.   buf += j;
  661.   size -= j;
  662.  
  663.   for(i = 0; i < size; ++i)
  664.   {
  665.     buf[i] = buf[i+skip];
  666.   }
  667. }
  668.